<?php
/**
 * 字符串截取，支持中文和其他编码
 * @param string $str 需要转换的字符串
 * @param string $start 开始位置
 * @param string $length 截取长度
 * @param string $charset 编码格式
 * @param string $suffix 截断显示字符
 * @return string
 */
function msubstr($str, $start=0, $length, $charset="utf-8", $suffix=true) {
    $charset = strtolower($charset);
    if(function_exists("mb_substr"))
        $slice = mb_substr($str, $start, $length, $charset);
    elseif(function_exists('iconv_substr')) {
        $slice = iconv_substr($str,$start,$length,$charset);
        if(false === $slice) {
            $slice = '';
        }
    }else{
        $re['utf-8']   = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
        $re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
        $re['gbk']    = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
        $re['big5']   = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";
        preg_match_all($re[$charset], $str, $match);
        $slice = join("",array_slice($match[0], $start, $length));
    }
    return $suffix ? $slice.'...' : $slice;
}

/**
 * 检测输入的验证码是否正确
 * @param string $code 为用户输入的验证码字符串
 * @return boolen
 */
function check_verify($code, $id = ''){
    $verify = new \Think\Verify();
    return $verify->check($code, $id);
}

/**
 * 对用户的密码进行加密
 * @param string $password
 * @param string $encrypt //传入加密串，在修改密码时做认证
 * @return array/password
 */
function password($password, $encrypt='') {

	//Log::write($encrypt, Log::INFO);
	$pwd = array();
	$pwd['encrypt'] =  $encrypt ? $encrypt : Org\Util\String::randString(6);
	$pwd['password'] = md5(md5(trim($password)).$pwd['encrypt']);
	return $encrypt ? $pwd['password'] : $pwd;
}

/**
 * 解析多行sql语句转换成数组
 * @param string $sql
 * @return array
 */
function sql_split($sql) {
	$sql = str_replace("\r", "\n", $sql);
	$ret = array();
	$num = 0;
	$queriesarray = explode(";\n", trim($sql));
	unset($sql);
	foreach($queriesarray as $query) {
		$ret[$num] = '';
		$queries = explode("\n", trim($query));
		$queries = array_filter($queries);
		foreach($queries as $query) {
			$str1 = substr($query, 0, 1);
			if($str1 != '#' && $str1 != '-') $ret[$num] .= $query;
		}
		$num++;
	}
	return($ret);
}

/**
 * 格式化字节大小
 * @param  number $size      字节数
 * @param  string $delimiter 数字和单位分隔符
 * @return string            格式化后的带单位的大小
 * @author 麦当苗儿 <zuojiazi@vip.qq.com>
 */
function format_bytes($size, $delimiter = '') {
    $units = array('B', 'KB', 'MB', 'GB', 'TB', 'PB');
    for ($i = 0; $size >= 1024 && $i < 5; $i++) $size /= 1024;
    return round($size, 2) . $delimiter . $units[$i];
}

/**
 * 取得文件扩展
 * @param $filename 文件名
 * @return 扩展名
 */
function file_ext($filename) {
	return strtolower(trim(substr(strrchr($filename, '.'), 1, 10)));
}

/**
 * 文件是否存在
 * @param string $filename  文件名
 * @return boolean
 */
function file_exist($filename ,$type=''){
	switch (STORAGE_TYPE){
		case 'Sae':
			$arr = explode('/', ltrim($filename, './'));
	        $domain = array_shift($arr);
	        $filePath = implode('/', $arr);
	        $s = new SaeStorage();
			return $s->fileExists($domain, $filePath);
			break;
		default:
			return \Think\Storage::has($filename ,$type);
	}
}

/**
 * 文件内容读取
 * @param string $filename  文件名
 * @return boolean
 */
function file_read($filename, $type=''){
	switch (STORAGE_TYPE){
		case 'Sae':
			$arr = explode('/', ltrim($filename, './'));
	        $domain = array_shift($arr);
			$filePath = implode('/', $arr);
			$s=new SaeStorage();
			return $s->read($domain, $filePath);
			break;
		default:
			return \Think\Storage::read($filename, $type);
	}
}

/**
 * 文件写入
 * @param string $filename  文件名
 * @param string $content  文件内容
 * @return boolean
 */
function file_write($filename, $content, $type=''){
	switch (STORAGE_TYPE){
		case 'Sae':
			$s=new SaeStorage();
			$arr = explode('/',ltrim($filename,'./'));
			$domain = array_shift($arr);
			$save_path = implode('/',$arr);
			return $s->write($domain, $save_path, $content);
			break;
		default:
			return \Think\Storage::put($filename, $content, $type);
	}
}

/**
 * 文件删除
 * @param string $filename  文件名
 * @return boolean
 */
function file_delete($filename ,$type=''){
	switch (STORAGE_TYPE){
		case 'Sae':
			$arr = explode('/', ltrim($filename, './'));
	        $domain = array_shift($arr);
	        $filePath = implode('/', $arr);
	        $s = new SaeStorage();
			return $s->delete($domain, $filePath);
			break;
		default:
			return \Think\Storage::unlink($filename ,$type);
	}
}

/**
 * 获取文件URL
 * @param string $filename  文件名
 * @return string
 */
function file_path2url($filename){
	$search = array_keys(C('TMPL_PARSE_STRING'));
	$replace = array_values(C('TMPL_PARSE_STRING'));
	return str_ireplace($search, $replace, $filename);
}
/**
 * 获取文件路径
 * @param string $fileurl  文件URL
 * @return string
 */
function file_url2path($fileurl){
	$search = array_values(C('TMPL_PARSE_STRING'));
	$replace = array_keys(C('TMPL_PARSE_STRING'));
	return str_ireplace($search, $replace, $fileurl);
}

function getThumb($url,$thumbName){
	$flieinfo = explode('.',$url);
	$path =  $flieinfo[0].'_'.$thumbName.'.'.$flieinfo[1];
	if(file_exist(SITE_DIR.$path)){
		return $path;
	}
	return $url;
}
/**
 * 添加用户消费记录
 * @param $orderid
 * @return bool
 */
function addConsumption($orderid)
{
	$consume_record_db = M('Member_consume_record');
	$card_records = $consume_record_db->where('orderid =' . $orderid )->select();
	if(count($card_records)==0){
		return false;
	}
	//消费用户所拥有的卡片
	$carddb = M('Member_card');
	foreach ($card_records as $card_record) {
		if($card_record['cardid']!=-1){
			$card = $carddb->where('id=' . $card_record['cardid'] . ' and mbid=' . $card_record['mbid'])->find();
			$update = array();
			if ($card_record['type'] == 0) {
				$update['laundry_count_surplus'] = $card['laundry_count_surplus'] - $card_record['use'];
			} else if ($card_record['type'] == 1) {
				$update['luxury_surplus'] = $card['luxury_surplus'] - $card_record['use'];
			}
			if (!empty($update)) {
				$carddb->where('id=' . $card_record['cardid'] . ' and mbid=' . $card_record['mbid'])->save($update);
			}
		}
		$consume_record_db->where('id=' . $card_record['id'])->save(array('status' => 1, 'usetime' => time()));
	}
	return true;
}

/*
 * http request tool
 */
/*
 * get method
 */
function get($url, $param=array()){
	if(!is_array($param)){
		throw new Exception("参数必须为array");
	}
	$p='';
	foreach($param as $key => $value){
		$p=$p.$key.'='.$value.'&';
	}
	if(preg_match('/\?[\d\D]+/',$url)){//matched ?c
		$p='&'.$p;
	}else if(preg_match('/\?$/',$url)){//matched ?$
		$p=$p;
	}else{
		$p='?'.$p;
	}
	$p=preg_replace('/&$/','',$p);
	$url=$url.$p;
	//echo $url;
	$httph =curl_init($url);
	curl_setopt($httph, CURLOPT_SSL_VERIFYPEER, 0);
	curl_setopt($httph, CURLOPT_SSL_VERIFYHOST, 1);
	curl_setopt($httph,CURLOPT_RETURNTRANSFER,1);
	curl_setopt($httph, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)");
	curl_setopt($httph, CURLOPT_RETURNTRANSFER,1);
	curl_setopt($httph, CURLOPT_HEADER,1);
	$rst=curl_exec($httph);
	curl_close($httph);
	return $rst;
}
/*
 * post method
 */
function post($url, $param=array()){
	if(!is_array($param)){
		throw new Exception("参数必须为array");
	}
	$httph =curl_init($url);
	curl_setopt($httph, CURLOPT_SSL_VERIFYPEER, 0);
	curl_setopt($httph, CURLOPT_SSL_VERIFYHOST, 1);
	curl_setopt($httph,CURLOPT_RETURNTRANSFER,1);
	curl_setopt($httph, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)");
	curl_setopt($httph, CURLOPT_POST, 1);//设置为POST方式
	curl_setopt($httph, CURLOPT_POSTFIELDS, $param);
	curl_setopt($httph, CURLOPT_RETURNTRANSFER,true);
//	curl_setopt($httph, CURLOPT_HEADER, false); //设定是否输出页面内容
//	curl_setopt($httph, CURLOPT_NOBODY, false);
	$rst=curl_exec($httph);
	curl_close($httph);
	return $rst;
}

// $string： 明文 或 密文
// $operation：DECODE表示解密,其它表示加密
// $key： 密匙
// $expiry：密文有效期
function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
	// 动态密匙长度，相同的明文会生成不同密文就是依靠动态密匙
	$ckey_length = 4;

	// 密匙
	$key = md5($key ? $key : C('AU_KEY'));

	// 密匙a会参与加解密
	$keya = md5(substr($key, 0, 16));
	// 密匙b会用来做数据完整性验证
	$keyb = md5(substr($key, 16, 16));
	// 密匙c用于变化生成的密文
	$keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';
	// 参与运算的密匙
	$cryptkey = $keya.md5($keya.$keyc);
	$key_length = strlen($cryptkey);
	// 明文，前10位用来保存时间戳，解密时验证数据有效性，10到26位用来保存$keyb(密匙b)，解密时会通过这个密匙验证数据完整性
	// 如果是解码的话，会从第$ckey_length位开始，因为密文前$ckey_length位保存 动态密匙，以保证解密正确
	$string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
	$string_length = strlen($string);
	$result = '';
	$box = range(0, 255);
	$rndkey = array();
	// 产生密匙簿
	for($i = 0; $i <= 255; $i++) {
		$rndkey[$i] = ord($cryptkey[$i % $key_length]);
	}
	// 用固定的算法，打乱密匙簿，增加随机性，好像很复杂，实际上对并不会增加密文的强度
	for($j = $i = 0; $i < 256; $i++) {
		$j = ($j + $box[$i] + $rndkey[$i]) % 256;
		$tmp = $box[$i];
		$box[$i] = $box[$j];
		$box[$j] = $tmp;
	}
	// 核心加解密部分
	for($a = $j = $i = 0; $i < $string_length; $i++) {
		$a = ($a + 1) % 256;
		$j = ($j + $box[$a]) % 256;
		$tmp = $box[$a];
		$box[$a] = $box[$j];
		$box[$j] = $tmp;
		// 从密匙簿得出密匙进行异或，再转成字符
		$result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
	}
	if($operation == 'DECODE') {
		// substr($result, 0, 10) == 0 验证数据有效性
		// substr($result, 0, 10) - time() > 0 验证数据有效性
		// substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16) 验证数据完整性
		// 验证数据有效性，请看未加密明文的格式
		if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
			return substr($result, 26);
		} else {
			return '';
		}
	} else {
		// 把动态密匙保存在密文里，这也是为什么同样的明文，生产不同密文后能解密的原因
		// 因为加密后的密文可能是一些特殊字符，复制过程可能会丢失，所以用base64编码
		return $keyc.str_replace('=', '', base64_encode($result));
	}

    /**
     *  @desc 根据两点间的经纬度计算距离
     *  @param float $lat 纬度值
     *  @param float $lng 经度值
     */

}
function getDistance($lat1, $lng1, $lat2, $lng2)
{
    $theta = $lng1 - $lng2;
    $miles = (sin(deg2rad($lat1)) * sin(deg2rad($lat2))) + (cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta)));
    $miles = acos($miles);
    $miles = rad2deg($miles);
    $miles = $miles * 60 * 1.1515;
    $feet = $miles * 5280;
    $yards = $feet / 3;
    return $kilometers = $miles * 1.609344;
//    $earthRadius = 6367000; //approximate radius of earth in meters
    /*
      Convert these degrees to radians
      to work with the formula
    */

//    $lat1 = ($lat1 * pi() ) / 180;
//    $lng1 = ($lng1 * pi() ) / 180;
//
//    $lat2 = ($lat2 * pi() ) / 180;
//    $lng2 = ($lng2 * pi() ) / 180;
//
//    /*
//      Using the
//      Haversine formula
//
//      http://en.wikipedia.org/wiki/Haversine_formula
//
//      calculate the distance
//    */
//
//    $calcLongitude = $lng2 - $lng1;
//    $calcLatitude = $lat2 - $lat1;
//    $stepOne = pow(sin($calcLatitude / 2), 2) + cos($lat1) * cos($lat2) * pow(sin($calcLongitude / 2), 2);  $stepTwo = 2 * asin(min(1, sqrt($stepOne)));
//    $calculatedDistance = $earthRadius * $stepTwo;
//    return $calculatedDistance/1000;
}

/**
 * 通过code换取网页授权access_token
 * @param $appId
 * @param $appSecret
 * @param $code
 * @param $path
 * @return mixed
 */
function getOauth2AccessToken($appId,$appSecret,$code,$path,$cache=false) {
	//access_token 应该全局存储与更新，以下代码以写入到文件中做示例
	$data = json_decode(file_get_contents($path ));
	if(!$cache){
		$data->expire_time = 0;
	}
	if ($data->expire_time < time()) {
		// 如果是企业号用以下URL获取access_token
		// $url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=$this->appId&corpsecret=$this->appSecret";
//		$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$appId&secret=$appSecret";
		$url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid='.$appId.'&secret='.$appSecret.'&code='.$code.'&grant_type=authorization_code';
		$data = json_decode(httpGet($url));
		$access_token = $data->access_token;
		if ($access_token&&$cache) {
			$data->expire_time = time() + 7000;
			$data->access_token = $access_token;
			$fp = fopen($path, "w");
			fwrite($fp, json_encode($data));
			fclose($fp);
		}
	}
	return $data;
}


/**
 * 获取js接口调用凭据
 * @return mixed
 */
function getAccessToken($appId,$appSecret,$path)
{
	// access_token 应该全局存储与更新，以下代码以写入到文件中做示例

	$data = json_decode(file_get_contents($path));
	if ($data->expire_time < time()) {
		// 如果是企业号用以下URL获取access_token
		$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&p=1&appid=" . $appId . "&secret=" . $appSecret;
		$res = json_decode(httpGet($url));
		$access_token = $res->access_token;
		if ($access_token) {
			$data->expire_time = time() + 7000;
			$data->access_token = $access_token;
			$fp = fopen($path, "w");
			fwrite($fp, json_encode($data));
			fclose($fp);
		}
	} else {
		$access_token = $data->access_token;
	}
	return $access_token;
}

/**
 * 获取js apiTicket
 * @param $appId
 * @param $appSecret
 * @param $path
 * @param $tockenpath
 * @return mixed
 */
function getJsApiTicket($appId,$appSecret,$path,$tockenpath){
	// jsapi_ticket 应该全局存储与更新，以下代码以写入到文件中做示例
	$data = json_decode(file_get_contents($path));
	if ($data->expire_time < time()) {
		$sccess_tocken = getAccessToken($appId,$appSecret, $tockenpath);
		// 如果是企业号用以下 URL 获取 ticket
		// $url = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=$accessToken";
		$url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=$sccess_tocken";
		$res = json_decode(httpGet($url));
		$ticket = $res->ticket;
		if ($ticket) {
			$data->expire_time = time() + 7000;
			$data->jsapi_ticket = $ticket;
			$fp = fopen($path, "w");
			fwrite($fp, json_encode($data));
			fclose($fp);
		}
	} else {
		$ticket = $data->jsapi_ticket;
	}
	return $ticket;
}
function createNonceStr($length = 16)
{
	$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
	$str = "";
	for ($i = 0; $i < $length; $i++) {
		$str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
	}
	return $str;
}

 function httpGet($url)
{
	$curl = curl_init();
	curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
	curl_setopt($curl, CURLOPT_TIMEOUT, 500);
	curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
	curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
	curl_setopt($curl, CURLOPT_URL, $url);
	$res = curl_exec($curl);
	curl_close($curl);
	return $res;
}


function array_to_xml($array) {
	if(is_object($array)){
		$array = get_object_vars($array);
	}
	$xml = '';
	foreach($array as $key => $value){
		$_tag = $key;
		$_id = null;
		if(is_numeric($key)){
			$_tag = 'item';
			$_id = ' id="' . $key . '"';
		}
		$xml .= "<{$_tag}{$_id}>";
		$xml .= ((is_array($value) || is_object($value)) ? array_to_xml($value) : ($value));
		$xml .= "</{$_tag}>";
	}
	return $xml;
}

function xml_to_array( $xml ){
	$reg = "/<(\\w+)[^>]*?>([\\x00-\\xFF]*?)<\\/\\1>/";
	if(preg_match_all($reg, $xml, $matches)){
		$count = count($matches[0]);
		$arr = array();
		for($i = 0; $i < $count; $i++){
			$key= $matches[1][$i];
			$val = xml_to_array( $matches[2][$i] );  // 递归
			if(array_key_exists($key, $arr)){
				if(is_array($arr[$key])){
					if(!array_key_exists(0,$arr[$key])){
						$arr[$key] = array($arr[$key]);
					}
				}else{
					$arr[$key] = array($arr[$key]);
				}
				$arr[$key][] = $val;
			}else{
				$arr[$key] = $val;
			}
		}
		return $arr;
	}else{
		return $xml;
	}
}

function curl_post_ssl($url, $vars, $second=30,$aHeader=array()){

	$ch = curl_init();
	curl_setopt($ch,CURLOPT_TIMEOUT,$second);
	curl_setopt($ch,CURLOPT_RETURNTRANSFER, 1);
	//curl_setopt($ch,CURLOPT_PROXY, '10.206.30.98');
	//curl_setopt($ch,CURLOPT_PROXYPORT, 8080);
	curl_setopt($ch,CURLOPT_URL,$url);
	curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
	curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false);

//        echo SITE_DIR.'/Apps/Common/Lib/cert/apiclient_cert.pem';exit();
//        curl_setopt($ch,CURLOPT_SSLCERT,getcwd().'/all.pem');
	curl_setopt($ch,CURLOPT_SSLCERT,SITE_DIR.'/Apps/Common/Lib/cert/apiclient_cert.pem');
	curl_setopt($ch,CURLOPT_SSLKEY,SITE_DIR.'/Apps/Common/Lib/cert/apiclient_key.pem');
	curl_setopt($ch,CURLOPT_CAINFO,SITE_DIR.'/Apps/Common/Lib/cert/rootca.pem');
	if( count($aHeader) >= 1 ){
		curl_setopt($ch, CURLOPT_HTTPHEADER, $aHeader);
	}
	curl_setopt($ch,CURLOPT_POST, 1);
	curl_setopt($ch,CURLOPT_POSTFIELDS,$vars);
	$data = curl_exec($ch);
	if($data){
		curl_close($ch);
		return $data;
	}
	else {
		$error = curl_errno($ch);
		echo "call faild, errorCode:$error\n";
		curl_close($ch);
		return false;
	}
}

function getEditAddress(){
	$WEIXIN = C('WEIXIN');
	$path =  C('ACCESS_TOKEN_PATH');
	$sccess_tocken = getAccessToken($WEIXIN['appId'],$WEIXIN['appSecret'], $path. "access_token.json");
	$data = array();
	$data["appid"] = $WEIXIN['appId'];
	$data["url"] = "http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
	$time = time();
	$data["timestamp"] = "$time";
	$data["noncestr"] = createNonceStr(8);
	$data["accesstoken"] = $sccess_tocken;
	ksort($data);
	$params = ToUrlParams($data);
	$addrSign = sha1($params);

	$afterData = array(
		"addrSign" => $addrSign,
		"signType" => "sha1",
		"scope" => "jsapi_address",
		"appId" => $WEIXIN['appId'],
		"timeStamp" => $data["timestamp"],
		"nonceStr" => $data["noncestr"]
	);
	return $editAddress = json_encode($afterData);


}
function ToUrlParams($urlObj)
{
	$buff = "";
	foreach ($urlObj as $k => $v)
	{
		if($k != "sign"){
			$buff .= $k . "=" . $v . "&";
		}
	}

	$buff = trim($buff, "&");
	return $buff;
}

//这个星期的星期一
// @$timestamp ，某个星期的某一个时间戳，默认为当前时间
// @is_return_timestamp ,是否返回时间戳，否则返回时间格式
function this_monday($timestamp=0,$is_return_timestamp=true){
	static $cache ;
	$id = $timestamp.$is_return_timestamp;
	if(!isset($cache[$id])){
		if(!$timestamp) $timestamp = time();
		$monday_date = date('Y-m-d', $timestamp-86400*date('w',$timestamp)+(date('w',$timestamp)>0?86400:-518400));
		if($is_return_timestamp){
			$cache[$id] = strtotime($monday_date);
		}else{
			$cache[$id] = $monday_date;
		}
	}
	return $cache[$id];

}

//这个星期的星期天
// @$timestamp ，某个星期的某一个时间戳，默认为当前时间
// @is_return_timestamp ,是否返回时间戳，否则返回时间格式
function this_sunday($timestamp=0,$is_return_timestamp=true){
	static $cache ;
	$id = $timestamp.$is_return_timestamp;
	if(!isset($cache[$id])){
		if(!$timestamp) $timestamp = time();
		$sunday = this_monday($timestamp) + /*6*86400*/518400+86400;
		if($is_return_timestamp){
			$cache[$id] = $sunday;
		}else{
			$cache[$id] = date('Y-m-d',$sunday);
		}
	}
	return $cache[$id];
}

//这个月的第一天
// @$timestamp ，某个月的某一个时间戳，默认为当前时间
// @is_return_timestamp ,是否返回时间戳，否则返回时间格式

function month_firstday($timestamp = 0, $is_return_timestamp=true){
	static $cache ;
	$id = $timestamp.$is_return_timestamp;
	if(!isset($cache[$id])){
		if(!$timestamp) $timestamp = time();
		$firstday = date('Y-m-d', mktime(0,0,0,date('m',$timestamp),1,date('Y',$timestamp)));
		if($is_return_timestamp){
			$cache[$id] = strtotime($firstday);
		}else{
			$cache[$id] = $firstday;
		}
	}
	return $cache[$id];
}

function month_lastday($timestamp = 0, $is_return_timestamp=true){
	static $cache ;
	$id = $timestamp.$is_return_timestamp;
	if(!isset($cache[$id])){
		if(!$timestamp) $timestamp = time();
		$lastday = date('Y-m-d 23:59:59', mktime(0,0,0,date('m',$timestamp),date('t',$timestamp),date('Y',$timestamp)));
		if($is_return_timestamp){
			$cache[$id] = strtotime($lastday);
		}else{
			$cache[$id] = $lastday;
		}
	}
	return $cache[$id];
}

/*
 * 车辆排序
 */
function car_sort($load,$site){
    //1.先找出开启工作状态的外部车辆，并且未接有订单
    $car=M('car');
    $time=date('d');
    $wb=$car->where(['type'=>1,'status'=>0])->field('mileage,y_time,id,type,channel_id')->select();//外部
    //,'site'=>$site,'load'=>['gt',$load]
    if($time==1){
        $nb=$car->where(['type'=>0,'status'=>0])->field('mileage,y_time,id,type,channel_id')->order()->select();//内部
        
    }else{
        $nb=$car->where(['type'=>0,'status'=>0])->field('mileage,y_time,id,type,channel_id')->select();//内部
        $arr=[];
        foreach ($nb as $v){
            $v['fen']=($v['mileage']*0.6)+($v['y_time']*0.4);//内部车公式排序
            $arr[]=$v;
        }
    }
   
    $nb=my_sort($arr,$arr['fen']);
    return array_merge($wb,$nb);
}


function my_sort($arrays,$sort_key,$sort_order=SORT_ASC,$sort_type=SORT_NUMERIC ){
    if(is_array($arrays)){
        foreach ($arrays as $array){
            if(is_array($array)){
                $key_arrays[] = $array[$sort_key];
            }else{
                return false;
            }
        }
    }else{
        return false;
    }
    array_multisort($key_arrays,$sort_order,$sort_type,$arrays);
    return $arrays;
}